﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace Zxb.DayWork.Logic
{
    public class HitWorkerProxy : Zxb.DayWork.Core.IRun
    {
        private int days;

        public HitWorkerProxy(int pastdays)
        {
            days = pastdays;
        }

        public void Run()
        {
            for (int i = days; i < 0; i++)
            {
                HitWorker hit = new HitWorker(DateTime.Now.AddDays(i));
                hit.Run();
            }
        }
    }

    public class HitWorker : BatchWorker
    {
        DataTable dtCaseEstate;
        DataTable dtCaseInfoHits;
        DataTable dtEstate4sCaseListHits;
        DataTable dtEstateNewCases;
        DataTable targetTable;
        DateTime startDay;
        DateTime endDay;
        private bool quit = false;

        public HitWorker()
        {
            endDay = DateTime.Now;
            startDay = endDay.AddDays(-1.0);
        }
        public HitWorker(DateTime statDay)
        {
            startDay = statDay;
            endDay = statDay.AddDays(1.0);
        }

        protected override void ReadData()
        {
            dtCaseEstate = GetMap_Case_Estate();
            dtCaseInfoHits = ReadDt_Case_DayHits(startDay,endDay);
            if (dtCaseInfoHits == null)
            {
                quit = true;
                return;
            }
            dtEstate4sCaseListHits = ReadDt_Estate_CaseListDayHits(startDay,endDay);
            dtEstateNewCases = ReadDt_Estate_NewCases(startDay,endDay);
        }

        protected override void ProcessData()
        {
            if (quit)
            {
                return;
            }
            targetTable = PrepareSchemaUdtEstateStatUpZxbHit();

            Random rm = new Random(DateTime.Now.Millisecond);

            var query_CaseEstate_Join_CaseInfoHits
                = from e in dtCaseEstate.AsEnumerable()
                  join h in dtCaseInfoHits.AsEnumerable()
                  on e.Field<int>("CaseID") equals h.Field<int>("ObjectID") into eh
                  from item in eh.DefaultIfEmpty()
                  select new
                  {
                      RealEstateID = e.Field<long>("RealEstateID"),
                      CaseID = e.Field<int>("CaseID"),
                      //Hits_Count = (item == null) ? 0 : item.Field<int>("Hits_Count") * 5 + rm.Next(-4, 5)
                      Hits_Count = (item == null) ? 0 : item.Field<int>("Hits_Count")
                  }; 
            var query_Estate_CaseInfoHits
                = from p in query_CaseEstate_Join_CaseInfoHits
                  group p by p.RealEstateID into g
                  select new
                  {
                      EstateID = g.Key,
                      DayHits = g.Sum(x => x.Hits_Count)
                  };

            
            var query_CaseHits_Merge_CaseListHits
                = from e in query_Estate_CaseInfoHits
                  join h in dtEstate4sCaseListHits.AsEnumerable()
                  on e.EstateID equals h.Field<long>("EstateID") into eh
                  from item in eh.DefaultIfEmpty()
                  select new
                  {
                      RealEstateID = e.EstateID,
                      DayCaseInfoHits = e.DayHits,
                      DayCaseListHits = (item == null) ? 0 : item.Field<int>("Hits_Count")
                  };
            
            var query_CaseHits_Merge_CaseListHits_Merge_NewCases
                = from e in query_CaseHits_Merge_CaseListHits
                  join c in dtEstateNewCases.AsEnumerable()
                  on e.RealEstateID equals c.Field<long>("RealEstateID") into ec
                  from item in ec.DefaultIfEmpty()
                  select new
                  {
                      RealEstateID = e.RealEstateID,
                      DayCaseInfoHits = e.DayCaseInfoHits,
                      DayCaseListHits = e.DayCaseListHits,
                      DayNewCaseNum = (item == null) ? 0 : item.Field<int>("DayNewCaseNum")
                  };
            var query_FilterNull
                = from e in query_CaseHits_Merge_CaseListHits_Merge_NewCases
                  where e.DayNewCaseNum > 0 || e.DayCaseInfoHits > 0 || e.DayCaseListHits > 0
                  select new
                  {
                      RealEstateID = e.RealEstateID,
                      DayCaseInfoHits = e.DayCaseInfoHits,
                      DayCaseListHits = e.DayCaseListHits,
                      DayNewCaseNum = e.DayNewCaseNum
                  };

            foreach (var item in query_FilterNull)
            {
                DataRow row = targetTable.NewRow();
                row["RealEstateID"] = item.RealEstateID;
                row["StatDate"] = startDay.ToString("yyyy-MM-dd 00:00");
                row["DayCaseInfoHits"] = item.DayCaseInfoHits;
                row["DayCaseListHits"] = item.DayCaseListHits;
                row["DayNewCaseNum"] = item.DayNewCaseNum;
                targetTable.Rows.Add(row);
            }
         }

        protected override void WriteData()
        {
            if (quit)
            {
                return;
            }
            DAL.TVPUpdate(targetTable, "EstateStatUpZxbHit", "UdtEstateStatZxbHit");
        }

        #region DAL
        private static DataTable PrepareSchemaUdtEstateStatUpZxbHit()
        {
            DataTable dt = new DataTable();
            dt.Columns.AddRange(new DataColumn[]
            { 
                new DataColumn("RealEstateID",typeof(long)),
                new DataColumn("StatDate",typeof(DateTime)),
                new DataColumn("DayNewCaseNum",typeof(int)),
                new DataColumn("DayCaseListHits",typeof(int)),
                new DataColumn("DayCaseInfoHits",typeof(int))
            });
            return dt;
        }

        private static DataTable GetMap_Case_Estate()
        {
            string sql = string.Format("select CaseID,RealEstateID from Cases with(nolock) where RealEstateID>0");
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.TaskReader, sql);
        }
        private static DataTable ReadDt_Case_DayHits(DateTime start, DateTime end)
        {
            string sql = string.Format("select ObjectID,SUM(RandCount) as Hits_Count from HitsWeiKe_Real h with(nolock) where TypeID=5 and h.VisitTime>='{0}' and h.VisitTime<'{1}' and ObjectID>0 group by ObjectID;", start.ToString("yyyy-MM-dd 00:00"), end.ToString("yyyy-MM-dd 00:00"));
            //return DAL.ReadDt_ReturnNewIfNull(DB.Home_logAdmin, sql);
            return DAL.ReadDt_Retry(DB.Home_logAdmin, sql);
        }
        private static DataTable ReadDt_Estate_CaseListDayHits(DateTime start, DateTime end)
        {
            string sql = string.Format("select EstateID,COUNT(1) as Hits_Count from HitsWeiKe_Estate with(nolock) where EstateID>20 and VisitTime>='{0}' and VisitTime<'{1}' group by EstateID", start.ToString("yyyy-MM-dd 00:00"), end.ToString("yyyy-MM-dd 00:00"));
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.Home_logAdmin, sql);
        }
        private static DataTable ReadDt_Estate_NewCases(DateTime start, DateTime end)
        {
            string sql = string.Format("select RealEstateID,COUNT(1) as DayNewCaseNum from Cases with(nolock) where AddedTime>='{0}' and AddedTime<'{1}' and isValid=1 group by RealEstateID", start.ToString("yyyy-MM-dd 00:00"), end.ToString("yyyy-MM-dd 00:00"));
            return DAL.ReadDt_Retry_ReturnNewIfNull(DB.TaskReader, sql);
        }
        #endregion
    }
}
